package com.jy.admin.services.cashPocket;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.common.utils.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.jsoniter.output.JsonStream;
import com.jy.admin.db.dao.*;
import com.jy.admin.db.entity.*;
import com.jy.admin.enums.ApiTypeEnum;
import com.jy.admin.enums.GreatRoyalCollectionTagEnum;
import com.jy.admin.enums.OrderStatusEnum;
import com.jy.admin.enums.OrderSyncStatusEnum;
import com.jy.admin.jobs.BaseJobHandler;
import com.jy.admin.services.BaseCrawlerService;
import com.jy.admin.services.cashPocket.vo.*;
import com.jy.bo.common.conf.util.HttpUtil;
import com.robert.vesta.util.IdUtils;
import org.asynchttpclient.AsyncCompletionHandler;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Future;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2022/1/10
 * Time: 8:49 下午
 */
@Service
public class GreatRoyalService extends BaseCrawlerService {
    private static final Logger LOGGER = LoggerFactory.getLogger(GreatRoyalService.class);

    @Autowired
    private CeOrdersDetailDao ordersDetailDao;

    @Autowired
    private CeMerchantDao merchantDao;

    @Autowired
    private CeCommentPushLogDao commentPushLogDao;

    @Autowired
    private CeAgentAccountDao agentAccountDao;

    @PostConstruct
    public void init() {
        BaseJobHandler.merchantAndServiceMap.put("greatroyal", this);
    }

    @Override
    public boolean hasLogin(CeAgentAccountEntity agentAccount) {
        if (apolloConfigUtil.isLoginStatusUseCache()) {
            return agentAccount.getLoginStatus() == 1;
        }

        if (agentAccount.getLoginStatus() == 2) {
            LOGGER.error("== 账号 token不可用 ==,account:{}", agentAccount.getAccount());
            return false;
        }

        CeMerchantEntity merchant = merchantDao.queryMerchantByCode(agentAccount.getMerchantCode());
        String url = merchant.getApiDomain() + "/main/system";
        LOGGER.info("== 检测登陆 开始请求订单列表 ==,url:{}", url);

        Map<String, String> headers = getHeaders(agentAccount);
        Map<String, String> params = Maps.newHashMap();
        String result = HttpUtil.getPage(url, params, headers);

        if (StringUtils.isEmpty(result)) {
            LOGGER.error("== 请求接口数据出错 ==，account:{},api:{}", agentAccount.getAccount(), ApiTypeEnum.order_list.getType());
            return false;
        }

        if (result.contains("Welcome to SCP")) {
            LOGGER.error("== 请求接口成功 当前账号token无效==，account:{},api:{}", agentAccount.getAccount(), ApiTypeEnum.order_list.getType());
            agentAccount.setLoginStatus(2);
            agentAccountDao.updateByPrimaryKey(agentAccount);
            return false;
        }

        return true;
    }

    @Override
    public void refresh(CeAgentAccountEntity agentAccount) {

        updateOrderList(agentAccount);
        updateOrderDetailInfo(agentAccount);
    }

    @Override
    public void updateOrderList(CeAgentAccountEntity agentAccount) {
        CeMerchantEntity merchant = merchantDao.queryMerchantByCode(agentAccount.getMerchantCode());
        String url = merchant.getApiDomain() + "/collection/order/list-my?page=1&per-page=500";
        LOGGER.info("== 开始请求订单列表 ==,url:{}", url);
        Map<String, String> headers = getHeaders(agentAccount);
        Map<String, String> params = Maps.newHashMap();
        String result = HttpUtil.getPage(url, params, headers);

        JSONArray resultsList = new JSONArray();
        Document document = Jsoup.parse(result);
        Elements trs = document.select("table").select("tr");

        for (int i = 1; i < trs.size(); i++) {
            JSONObject element = new JSONObject();
            Elements tds = trs.get(i).select("td");

            for (int j = 0; j < tds.size(); j++) {
                if (tds.get(j).childNodes().size() <= 0) {
                    continue;
                }
                String value = tds.get(j).childNodes().get(0).toString();

                if (value.contains(",")) {
                    value = value.replace(",", "");
                }
                if (j == 0) {
                    element.put("product", value);
                } else if (j == 1) {
                    element.put("orderNo", value);
                } else if (j == 2) {
                    element.put("isOld", !value.equals("New Case") ? 2 : 1);
                } else if (j == 3) {
                    element.put("dueTime", value);
                } else if (j == 4) {
                    element.put("overdueDays", value);
                } else if (j == 5) {
                    element.put("name", value);
                } else if (j == 6) {
                    element.put("phone", value);
                } else if (j == 7) {
                    element.put("remainingAmount", value);
                } else if (j == tds.size()-1) {
                    String href = tds.get(j).childNodes().get(0).attributes().get("href");
                    element.put("href", href);
                    String id = href.substring(href.indexOf("id=") + 3);
                    element.put("id", id);

                }

            }
            if (!element.getString("remainingAmount").equals("0")) {
                resultsList.add(element);
            }
        }

        //查询今天该账号的所有有效订单
        List<CeOrdersEntity> activeOrders = ordersDao.getTodayListByStatusAndAgent(agentAccount.getAgentCode(), OrderStatusEnum.active.getStatus());

        if (CollectionUtils.isEmpty(activeOrders)) {
            LOGGER.info("== 存在未拉取订单 ==，agentCode:{},size:{}", agentAccount.getAgentCode(), resultsList.size());
            resultsList.forEach(item -> {
                try {
                    String orderNo = JsonIterator.deserialize(item.toString()).get("orderNo").toString();
                    CeOrdersEntity todayOneByOrderNo = ordersDao.getTodayOneByOrderNoAndAgentCode(orderNo, agentAccount.getAgentCode());
                    if (todayOneByOrderNo == null) {
                        LOGGER.info("==更新的时候发现有新的订单==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), orderNo);
                        CeOrdersEntity ceOrdersEntity = new CeOrdersEntity()
                                .setAgentCode(agentAccount.getAgentCode())
                                .setMerchantCode(agentAccount.getMerchantCode())
                                .setOrderNo(orderNo)
                                .setOrderInfo(item.toString())
                                .setStatus(OrderStatusEnum.active.getStatus())
                                .setCreateDt(new Date())
                                .setCollectionNo(IdUtils.genId() + "");
                        ordersDao.insert(ceOrdersEntity);
                    }
                } catch (Exception e) {
                    LOGGER.error("== 插入数据发生异常 ==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), JsonIterator.deserialize(item.toString()).get("orderNo").toString(), e);
                }
            });
        } else {
            resultsList.forEach(item -> {
                try {
                    String orderNo = JsonIterator.deserialize(item.toString()).get("orderNo").toString();
                    CeOrdersEntity OneByOrderNo = ordersDao.getTodayOneByOrderNoAndAgentCode(orderNo, agentAccount.getAgentCode());
                    if (OneByOrderNo == null) {
                        LOGGER.info("== 列表为空,插入订单 ==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), orderNo);
                        CeOrdersEntity ceOrdersEntity = new CeOrdersEntity()
                                .setAgentCode(agentAccount.getAgentCode())
                                .setMerchantCode(agentAccount.getMerchantCode())
                                .setOrderNo(orderNo)
                                .setOrderInfo(item.toString())
                                .setStatus(OrderStatusEnum.active.getStatus())
                                .setCreateDt(new Date())
                                .setCollectionNo(IdUtils.genId() + "");
                        ordersDao.insert(ceOrdersEntity);
                    }
                } catch (Exception e) {
                    LOGGER.error("== 插入数据发生异常 ==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), JsonIterator.deserialize(item.toString()).get("orderNo").toString(), e);
                }
            });
            LOGGER.info("== 订单减少 ==,agentCode:{}，size:{}", agentAccount.getAgentCode(), resultsList.size());
            activeOrders.forEach(item -> {
                try {
                    String id = JsonIterator.deserialize(item.getOrderInfo()).get("orderNo").toString();
                    boolean hasOrder = false;
                    for (int i = 0; i < resultsList.size(); i++) {
                        Any child = JsonIterator.deserialize(resultsList.get(i).toString());
                        String orderNo = child.get("orderNo").toString();
                        if (id.equals(orderNo)) {
                            LOGGER.info("== 当前订单存在 ==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), orderNo);
                            hasOrder = true;
                            break;
                        }

                    }
                    if (!hasOrder) {
                        LOGGER.info("== 当前订单不存在 ==,agentCode:{},orderNo:{}", agentAccount.getAgentCode(), id);
                        if (item.getStatus().equals(OrderStatusEnum.active.getStatus())) {
                            item.setStatus(OrderStatusEnum.updated.getStatus());
                            ordersDao.updateByPrimaryKey(item);
                        }
                    }
                } catch (Exception e) {
                    LOGGER.error("== 更新订单发生异常 ==,account:{},orderNo:{}", agentAccount.getAccount(), JsonIterator.deserialize(item.getOrderInfo()).get("id").toString(), e);
                }
            });

        }

        LOGGER.info("== 订单刷新处理完成 ==");

    }

    @Override
    public void updateOrderDetailInfo(CeAgentAccountEntity agentAccount) {
        List<CeOrdersEntity> activeOrders = ordersDao.getTodayListByStatusAndAgent(agentAccount.getAgentCode(), OrderStatusEnum.active.getStatus());
        if (CollectionUtils.isEmpty(activeOrders)) {
            return;
        }

        CeMerchantEntity merchant = merchantDao.queryMerchantByCode(agentAccount.getMerchantCode());

        Map<String, String> headers = getHeaders(agentAccount);
        LOGGER.info("== 构建header ==,header:{}", JsonStream.serialize(headers));

        Map<String, String> params = Maps.newHashMap();

        activeOrders.forEach(order -> {

            try {
                boolean hasDetailData = order.getDetailStatus() == 1;
                Any orderInfo = JsonIterator.deserialize(order.getOrderInfo());
                Map<String, String> infoMap = new HashMap<>();
                String baseInfoUrl = merchant.getApiDomain() + orderInfo.get("href").toString();
                String result = HttpUtil.getPage(baseInfoUrl, params, headers);
                LOGGER.info("== 获取成功 repaymentInfo==");


                Document document = Jsoup.parse(result);
                Elements tables = document.select("table");
                Elements trs = tables.get(0).select("tr");
                JSONObject repaymentDetail = new JSONObject();
                for (int i = 1; i < trs.size(); i++) {
                    Elements tds = trs.get(i).select("td");

                    for (int j = 0; j < tds.size(); j++) {
                        if (tds.get(j).childNodes().size() <= 0) {
                            continue;
                        }
                        String value = tds.get(j).childNodes().get(0).toString();

                        if (value.contains(",")) {
                            value = value.replace(",", "");
                        }
                        if (i == 1 && j == 0) {
                            repaymentDetail.put("phone", value);
                        } else if (i == 1 && j == 1) {
                            repaymentDetail.put("remainAmount", value);
                        } else if (i == 1 && j == 2) {
                            repaymentDetail.put("borrowAmount", value);
                        } else if (i == 1 && j == 3) {
                            repaymentDetail.put("lateFee", value);
                        } else if (i == 1 && j == 4) {
                            repaymentDetail.put("paidAmount", value);
                        } else if (i == 1 && j == 5) {
                            repaymentDetail.put("loanDate", value);
                        } else if (i == 1 && j == 6) {
                            repaymentDetail.put("dueDate", value);
                        } else if (i == 3 && j == 0) {
                            repaymentDetail.put("overdueDay", value);
                        } else if (i == 3 && j == 1) {
                            repaymentDetail.put("product", value);
                        } else if (i == 3 && j == 2) {
                            repaymentDetail.put("name", value);
                        } else if (i == 3 && j == 3) {
                            repaymentDetail.put("age", value);
                        } else if (i == 3 && j == 4) {
                            repaymentDetail.put("gender", value);
                        }

                    }
                }
                String remainMoney = repaymentDetail.getString("remainAmount");
                updateRemainMoney(order.getCollectionNo(), remainMoney);
                infoMap.put("repaymentInfo", repaymentDetail.toString());


                if (!hasDetailData) {
                    Elements imgTrs = tables.get(2).select("tr");
                    ArrayList<String> imgList = Lists.newArrayList();
                    for (int i = 1; i < imgTrs.size(); i++) {
                        Elements tds = imgTrs.get(i).select("th");

                        for (int j = 0; j < tds.size(); j++) {
                            if (tds.get(j).childNodes().size() <= 0) {
                                continue;
                            }
                            String value = tds.get(j).childNodes().get(0).toString();

                            if (value.contains(",")) {
                                value = value.replace(",", "");
                            }
                            if (i == 1 && j == 0) {
                                String src = tds.get(j).childNodes().get(0).attributes().get("src");
                                imgList.add(src);
                            } else if (i == 1 && j == 1) {
                                String src = tds.get(j).childNodes().get(0).attributes().get("src");
                                imgList.add(src);
                            } else if (i == 1 && j == 2) {
                                String src = tds.get(j).childNodes().get(0).attributes().get("src");
                                imgList.add(src);
                            } else if (i == 2 && j == 0) {
                                repaymentDetail.put("aadhaarNo", value);
                            } else if (i == 2 && j == 1) {
                                repaymentDetail.put("panNo", value);
                            }

                        }
                    }

                    infoMap.put("baseInfo", repaymentDetail.toString());
                    infoMap.put("images", JsonStream.serialize(imgList));

                    Elements contactTrs = tables.get(1).select("tr");
                    JSONArray contactArray = new JSONArray();
                    for (int i = 1; i < contactTrs.size(); i++) {
                        Elements tds = contactTrs.get(i).select("td");
                        JSONObject contactDetail = new JSONObject();

                        for (int j = 0; j < tds.size(); j++) {
                            if (tds.get(j).childNodes().size() <= 0) {
                                continue;
                            }
                            String value = tds.get(j).childNodes().get(0).toString();

                            if (value.contains(",")) {
                                value = value.replace(",", "");
                            }
                            if (j == 0) {
                                contactDetail.put("phone", value);
                            } else if (j == 1) {
                                contactDetail.put("name", value);
                            }
                        }
                        contactArray.add(contactDetail);
                    }
                    infoMap.put("contactInfo", contactArray.toString());

                    try {
                        Elements contactBookTrs = tables.get(3).select("td");
                        JSONArray contactBookList = new JSONArray();
                        int size = Math.min(contactBookTrs.size(), 1000);
                        for (int i = 0; i < size; i = i + 2) {
                            if (contactBookTrs.get(i).childNodes().size() <= 0) {
                                continue;
                            }
                            if (i + 1 >= size) {
                                break;
                            }
                            JSONObject child = new JSONObject();
                            String name = contactBookTrs.get(i).childNodes().get(0).toString();
                            child.put("name", name);
                            if (contactBookTrs.get(i + 1).childNodes().size() > 0) {
                                String phone = contactBookTrs.get(i + 1).childNodes().get(0).toString();
                                child.put("phone", phone.replaceAll(" ", ""));
                                if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(phone)) {
                                    contactBookList.add(child);
                                }
                            }

                        }
                        JSONObject jsonData = new JSONObject();
                        jsonData.put("contacts", contactBookList);

                        String contactUrl = uploadContact(order.getOrderNo(), jsonData.toString());
                        LOGGER.info("== 上传通讯录，得到地址 ==,url:{}", contactUrl);
                        infoMap.put("contactUrl", contactUrl);

                    } catch (Exception e) {
                        LOGGER.error("== 通讯录转换错误 ==", e);
                    }
                    infoMap.keySet().forEach(k -> {
                        CeOrdersDetailEntity byKeyAndMerchantAndOrderNo = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), k, order.getOrderNo());
                        if (byKeyAndMerchantAndOrderNo == null) {
                            CeOrdersDetailEntity ordersDetailEntity = new CeOrdersDetailEntity()
                                    .setOrderNo(order.getOrderNo())
                                    .setMerchantCode(order.getMerchantCode())
                                    .setDataKey(k)
                                    .setDetailInfo(infoMap.get(k));
                            ordersDetailDao.insert(ordersDetailEntity);
                        } else {
                            byKeyAndMerchantAndOrderNo.setDetailInfo(infoMap.get(k));
                            ordersDetailDao.updateByPrimaryKey(byKeyAndMerchantAndOrderNo);
                        }

                    });

                    order.setSyncStatus(OrderSyncStatusEnum.waiting.getStatus());
                } else {
                    infoMap.keySet().forEach(k -> {
                        CeOrdersDetailEntity byKeyAndMerchantAndOrderNo = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), k, order.getOrderNo());
                        byKeyAndMerchantAndOrderNo.setDetailInfo(infoMap.get(k));
                        ordersDetailDao.updateByPrimaryKey(byKeyAndMerchantAndOrderNo);
                    });
                }

                order.setDetailStatus(1);
                ordersDao.updateByPrimaryKey(order);
            } catch (Exception e) {
                LOGGER.error("== 程序处理有异常 ==", e);
                order.setDetailStatus(2);
                ordersDao.updateByPrimaryKey(order);
            }
        });

        LOGGER.info("== 程序处理完成 ==");
    }

    @Override
    public void compostCollectionData(CeAgentAccountEntity agentAccount) {
        LOGGER.info("== compostCollectionData ==");
        List<CeOrdersEntity> todayListBySyncStatusAndAgent = ordersDao.getTodayListBySyncStatusAndAgent(agentAccount.getAgentCode(), OrderSyncStatusEnum.waiting.getStatus());
        if (CollectionUtils.isEmpty(todayListBySyncStatusAndAgent)) {
            LOGGER.info("== compostCollectionData  没有需要同步的订单 ==，agentCode:{},syncStatus:{}", agentAccount.getAgentCode(), OrderSyncStatusEnum.waiting.getStatus());
            return;
        }

        LOGGER.info("== compostCollectionData  需要同步的订单 ==，size:{},account:{}", todayListBySyncStatusAndAgent.size(), agentAccount.getAccount());

        todayListBySyncStatusAndAgent.forEach(order -> {
            try {
                LOGGER.info("== 构建推送信息 基础信息 开始==,collectionNo:{},syncStatus:{}", order.getCollectionNo(), order.getSyncStatus());
                Any orderDetail = JsonIterator.deserialize(order.getOrderInfo());
                String appName = orderDetail.get("product").toString();
                ClOrderReceiveRequest request = new ClOrderReceiveRequest()
                        .setOrderBillNo(order.getCollectionNo())
                        .setTradeNo(order.getCollectionNo())
                        .setProductType(appName)
                        .setAppName(appName)
                        .setOriginOrderNo(order.getOrderNo())
                        .setAccount(order.getAgentCode())
                        .setAccount_id(agentAccount.getId())
                        .setClientCode(order.getMerchantCode())
                        .setProductCode(appName)
                        .setUserCode(IdUtils.genId() + "");

                CeOrdersDetailEntity emergencyContactInfo = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), "contactInfo", order.getOrderNo());
                Any emergencyContactInfoJson = JsonIterator.deserialize(emergencyContactInfo.getDetailInfo());

                CeOrdersDetailEntity personalInfo = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), "baseInfo", order.getOrderNo());
                Any personalInfoJson = JsonIterator.deserialize(personalInfo.getDetailInfo());

                CeOrdersDetailEntity repaymentInfo = ordersDetailDao.getByKeyAndMerchantAndOrderNoToday(order.getMerchantCode(), "repaymentInfo", order.getOrderNo());
                Any repaymentInfoJson = JsonIterator.deserialize(repaymentInfo.getDetailInfo());

                CeOrdersDetailEntity contactUrl = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), "contactUrl", order.getOrderNo());
                Any contactUrlJson = JsonIterator.deserialize(contactUrl.getDetailInfo());

                String borrowCapital = repaymentInfoJson.get("borrowAmount").toString();
                String actualAmount = repaymentInfoJson.get("borrowAmount").toString();
                String paidAmount = repaymentInfoJson.get("paidAmount").toString();
                String repaymentAmount = repaymentInfoJson.get("remainAmount").toString();
                String remainMoney = repaymentInfoJson.get("remainAmount").toString();
                String overdueDays = repaymentInfoJson.get("overdueDay").toString();
                String lateFee = repaymentInfoJson.get("lateFee").toString();

                LOGGER.info("== 构建推送信息 计算逾期罚息利率 开始==,borrowCapital:{}，overdueDays:{}.lateFee:{}", borrowCapital, overdueDays, lateFee);
                String overdueRatio = "0";
                if (!overdueDays.equals("0")) {
                    overdueRatio = new BigDecimal(lateFee).divide(new BigDecimal(overdueDays), 2, BigDecimal.ROUND_HALF_UP).divide(new BigDecimal(borrowCapital), 4, BigDecimal.ROUND_HALF_UP).toString();
                }
                LOGGER.info("== 构建推送信息 订单信息 开始==,collectionNo:{}", order.getCollectionNo());

                ClOrderInputVo orderInputVo = new ClOrderInputVo()
                        .setBorrowType(orderDetail.get("isOld").toInt())
                        .setBorrowCapital(borrowCapital)
                        .setChannel(appName)
                        .setAppLink("")
                        .setCapitalCode(appName)
                        .setInterest("0")
                        .setDeductAmount("0")
                        .setLateFeeRatio(overdueRatio)
                        .setServiceFee("0")
                        .setLateServiceFee("0")
                        .setReceivedCapital(actualAmount)
                        .setPaidAmount(paidAmount)
                        .setReceivedDate(repaymentInfoJson.get("loanDate").toString())
                        .setRepaymentDate(repaymentInfoJson.get("dueDate").toString())
                        .setRemainMoney(remainMoney)
                        .setTotalMoney(repaymentAmount);

                request.setOrderInfo(orderInputVo);

                LOGGER.info("== 构建推送信息 个人信息 开始==,collectionNo:{}", order.getCollectionNo());

                String pancardNo = personalInfoJson.get("panNo").toString();
                String aadhaarNo = personalInfoJson.get("aadhaarNo").toString();
                String email = "no";

                String companyCity = "no";
                String companyProvince = "no";
                String friendName = "no";
                String friendMobile = "no";

                String parentName = "no";
                String parentPhone = "no";

                List<Any> anies = emergencyContactInfoJson.asList();
                String personMobile = personalInfoJson.get("phone").toString();
                String personName = personalInfoJson.get("name").toString();

                if (anies.size() >= 2) {
                    parentName = anies.get(0).get("name").toString();
                    parentPhone = anies.get(0).get("phone").toString();
                    friendName = anies.get(1).get("name").toString();
                    friendMobile = anies.get(1).get("phone").toString();
                }

                CeOrdersDetailEntity imageInfo = ordersDetailDao.getByKeyAndMerchantAndOrderNo(order.getMerchantCode(), "images", order.getOrderNo());
                List<Any> imageList = JsonIterator.deserialize(imageInfo.getDetailInfo()).asList();

                List<String> images = new ArrayList<>();
                imageList.forEach(v -> {
                    images.add(v.toString());
                });

                int gender = personalInfoJson.get("gender").toString().equals("Male") ? 1 : 0;
                int age = personalInfoJson.get("age").toInt();
                String birthDay = (Integer.parseInt(DateUtil.getYear()) - age) + "-" + DateUtil.getMonth() + "-" + DateUtil.getDay();
                ClUserInfoInputVo userInfoInputVo = new ClUserInfoInputVo()
                        .setUserLanguage("")
                        .setAadhaarNo(aadhaarNo)
                        .setPanCardNo(pancardNo)
                        .setAddress("no")
                        .setBirthday(birthDay)
                        .setCity(companyCity)
                        .setState(companyProvince)
                        .setEmail(email)

                        .setContact1Mobile(parentPhone)
                        .setContact1Name(parentName)
                        .setContact1Relative(1)

                        .setContact2Mobile(friendMobile)
                        .setContact2Name(friendName)
                        .setContact2Relative(6)

                        .setEducation(0)
                        .setKycNo(aadhaarNo)
                        .setMobile(personMobile)

                        .setMarriedStatus(0)
                        .setName(personName)
                        .setPinCode("no")

                        .setSex(gender)
                        .setContactUrl(contactUrlJson.toString())
                        .setImages(images);

                request.setUserInfo(userInfoInputVo);

                LOGGER.info("== 构建推送信息 完成==,collectionNo:{}", order.getCollectionNo());

                CePushLogEntity pushLogEntity = pushLogDao.selectByCollectionNo(order.getCollectionNo());
                if (pushLogEntity == null) {
                    pushLogEntity = new CePushLogEntity()
                            .setCollectionNo(order.getCollectionNo())
                            .setDetailInfo(JsonStream.serialize(request))
                            .setStatus(1);
                    pushLogDao.insert(pushLogEntity);
                } else {
                    pushLogEntity.setDetailInfo(JsonStream.serialize(request));
                    pushLogDao.updateByPrimaryKey(pushLogEntity);
                }


                LOGGER.info("== 构建推送信息 保存信息完成==,collectionNo:{}", order.getCollectionNo());
                order.setSyncStatus(OrderSyncStatusEnum.data_ready.getStatus());
                ordersDao.updateByPrimaryKey(order);
            } catch (Exception e) {
                LOGGER.error("== 构建推送信息 发生异常==,collectionNo:{}", order.getCollectionNo(), e);
                order.setSyncStatus(OrderSyncStatusEnum.data_fail.getStatus());
                ordersDao.updateByPrimaryKey(order);
            }
        });

    }

    @Override
    public void pushDataToCollection(CeAgentAccountEntity agentAccount) {
        super.pushDataToCollection(agentAccount);
    }

    @Override
    public void checkOrdersPaidStatus(CeAgentAccountEntity agentAccount) {
        LOGGER.info("== 检查订单支付情况 ==");
        List<CeOrdersEntity> waitingPaidCheckOrders = ordersDao.getTodayListByStatusAndAgent(agentAccount.getAgentCode(), OrderStatusEnum.updated.getStatus());
        if (CollectionUtils.isEmpty(waitingPaidCheckOrders)) {
            LOGGER.info("== 检查订单支付情况 没有状态更新的订单==,size:{}", waitingPaidCheckOrders.size());
            return;
        }

        LOGGER.info("== 检查订单支付情况==,size:{}", waitingPaidCheckOrders.size());
        CeMerchantEntity merchant = merchantDao.queryMerchantByCode(agentAccount.getMerchantCode());
        Map<String, String> headers = getHeaders(agentAccount);
        LOGGER.info("== 构建header ==,header:{}", JsonStream.serialize(headers));
        Map<String, String> params = Maps.newHashMap();
        String url = merchant.getApiDomain() + "/collection/order/list-success?per-page=100&final_repayment_time=" + DateUtil.getDate("yyyy-MM-dd");
        LOGGER.info("== 开始请求已还款订单列表 ==,url:{}", url);
        String result = HttpUtil.getPage(url, params, headers);
        JSONArray repayList = new JSONArray();
        Document document = Jsoup.parse(result);
        Elements trs = document.select("table").select("tr");

        for (int i = 1; i < trs.size(); i++) {
            JSONObject element = new JSONObject();
            Elements tds = trs.get(i).select("td");

            for (int j = 0; j < tds.size(); j++) {
                if (tds.get(j).childNodes().size() <= 0) {
                    continue;
                }
                String value = tds.get(j).childNodes().get(0).toString();

                if (value.contains(",")) {
                    value = value.replace(",", "");
                }
                if (j == 4) {
                    element.put("orderNo", value);
                }
            }
            repayList.add(element);
        }
        LOGGER.info("== GreatRoyal成功还款列表 ==,list:{}", repayList.toString());
        waitingPaidCheckOrders.forEach(order -> {
            boolean isRepay = false;
            for (int i = 0; i < repayList.size(); i++) {
                LOGGER.info("==GreatRoyal 还款金额==,orderNo:{},reapyOrderNo:{}", order.getOrderNo(), repayList.getJSONObject(i).getString("orderNo"));
                if (order.getOrderNo().equals(repayList.getJSONObject(i).getString("orderNo"))) {
                    isRepay = true;
                    break;
                }
            }
            if (isRepay) {
                LOGGER.info("== 订单已还款 ==,OrderNo:{}", order.getOrderNo());
                order.setSyncStatus(OrderSyncStatusEnum.need_pay_update.getStatus());
                order.setStatus(OrderStatusEnum.paid_update.getStatus());
                ordersDao.updateByPrimaryKey(order);
                return;
            }
            LOGGER.info("== 订单未还款，移除订单 ==,orderNo:{}", order.getOrderNo());
            order.setStatus(OrderStatusEnum.removed.getStatus());
            order.setSyncStatus(OrderSyncStatusEnum.need_remove.getStatus());
            ordersDao.updateByPrimaryKey(order);

        });


    }

    @Override
    public void updatePaidOrderToCollection(CeAgentAccountEntity agentAccount) {
        LOGGER.info("== 开始同步有更新的数据到催收系统 ==");
        List<CeOrdersEntity> todayListBySyncStatusAndAgent = ordersDao.getTodayListBySyncStatusAndAgent(agentAccount.getAgentCode(), OrderSyncStatusEnum.need_pay_update.getStatus());
        if (CollectionUtils.isEmpty(todayListBySyncStatusAndAgent)) {
            LOGGER.info("== 开始同步有更新的数据到催收系统 没有还款订单==");
            return;
        }

        LOGGER.info("== 开始同步有更新的数据到催收系统 有还款==,size:{}", todayListBySyncStatusAndAgent.size());
        todayListBySyncStatusAndAgent.forEach(order -> {
            try {
                CeOrdersDetailEntity byKeyAndMerchantAndOrderNo = ordersDetailDao.getByKeyAndMerchantAndOrderNoToday(order.getMerchantCode(), "repaymentInfo", order.getOrderNo());
                Any deserialize = JsonIterator.deserialize(byKeyAndMerchantAndOrderNo.getDetailInfo());
                String paidAmount = deserialize.get("paidAmount").toString();
                ClRepaymentRequest request = new ClRepaymentRequest()
                        .setDeductAmount("0")
                        .setOrderBillNo(order.getCollectionNo())
                        .setPaidAmount(paidAmount)
                        .setPaidStatus(2)
                        .setPaidType(1)
                        .setRepayBizNo(IdUtils.genId() + "")
                        .setRepayDate(DateUtil.getDate(new Date(), "yyyy-MM-dd HH:mm:ss"))
                        .setToken("a481e307fd3343c4faca93ADAFb8a3892ee1")
                        .setTotalDeductAmount("0")
                        .setTotalPaidAmount(paidAmount)
                        .setTradeNo(order.getCollectionNo());

                HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "application/json;charset=utf-8");

                HttpEntity requestPush = new HttpEntity(JsonStream.serialize(request), headers);
                ResponseEntity responseEntity = new RestTemplate().postForEntity(apolloConfigUtil.getCollectionRepayPushUrl(), requestPush, String.class);
                String responseStr = responseEntity.getBody().toString();
                LOGGER.info("=======  推送collection请求结果  ======:{},method:{}", responseStr, apolloConfigUtil.getCollectionRepayPushUrl());
                if (JsonIterator.deserialize(responseStr).get("code").toString().equals("0")) {
                    LOGGER.info("== 开始同步有更新的数据到催收系统 推送还款成功==,orderNo:{}", order.getOrderNo());
                    order.setSyncStatus(OrderSyncStatusEnum.pay_update_success.getStatus());
                } else {
                    LOGGER.error("== 开始同步有更新的数据到催收系统 推送还款失败==,orderNo:{}", order.getOrderNo());
                    order.setSyncStatus(OrderSyncStatusEnum.pay_update_fail.getStatus());
                }
            } catch (Exception e) {
                LOGGER.error("=======  推送collection请求结果 error  ======", e);
                order.setSyncStatus(OrderSyncStatusEnum.pay_update_fail.getStatus());
            }
            ordersDao.updateByPrimaryKey(order);
        });

    }

    @Override
    public void updateRemovedOrderToCollection(CeAgentAccountEntity agentAccount) {
        LOGGER.info("==  updateRemovedOrderToCollection 开始同步有更新的数据到催收系统 ==");
//        List<CeOrdersEntity> todayListBySyncStatusAndAgent = ordersDao.getTodayListBySyncStatusAndAgent(agentAccount.getAgentCode(), OrderSyncStatusEnum.need_remove.getStatus());
//        if (CollectionUtils.isEmpty(todayListBySyncStatusAndAgent)) {
//            LOGGER.info("== 开始同步有更新的数据到催收系统 updateRemovedOrderToCollection 没有需要移除的订单==");
//            return;
//        }
//
//        LOGGER.info("== 开始同步有更新的数据到催收系统 updateRemovedOrderToCollection 有数据需要移除==,size:{}", todayListBySyncStatusAndAgent.size());
//        todayListBySyncStatusAndAgent.forEach(order -> {
//            try {
//                CeOrdersDetailEntity byKeyAndMerchantAndOrderNo = ordersDetailDao.getByKeyAndMerchantAndOrderNoToday(order.getMerchantCode(), "repaymentInfo", order.getOrderNo());
//                Any deserialize = JsonIterator.deserialize(byKeyAndMerchantAndOrderNo.getDetailInfo());
//                String paidAmount = deserialize.get("paidAmount").toString();
//                ClRepaymentRequest request = new ClRepaymentRequest()
//                        .setDeductAmount("0")
//                        .setOrderBillNo(order.getCollectionNo())
//                        .setPaidAmount(paidAmount)
//                        .setPaidStatus(2)
//                        .setPaidType(1)
//                        .setRepayBizNo(IdUtils.genId() + "")
//                        .setRepayDate(DateUtil.getDate(new Date(), "yyyy-MM-dd HH:mm:ss"))
//                        .setToken("a481e307fd3343c4faca93ADAFb8a3892ee1")
//                        .setTotalDeductAmount("0")
//                        .setTotalPaidAmount(paidAmount)
//                        .setTradeNo(order.getCollectionNo());
//
//                HttpHeaders headers = new HttpHeaders();
//                headers.set("Content-Type", "application/json;charset=utf-8");
//
//                HttpEntity requestPush = new HttpEntity(JsonStream.serialize(request), headers);
//                ResponseEntity responseEntity = new RestTemplate().postForEntity(apolloConfigUtil.getCollectionRepayPushUrl()_remove, requestPush, String.class);
//                String responseStr = responseEntity.getBody().toString();
//                LOGGER.info("=======  推送collection请求结果  ======:{},method:{}", responseStr, apolloConfigUtil.getCollectionRepayPushUrl()_remove);
//                if (JsonIterator.deserialize(responseStr).get("code").toString().equals("0")) {
//                    LOGGER.info("== 开始同步有更新的数据到催收系统 推送还款成功==,orderNo:{}", order.getOrderNo());
//                    order.setSyncStatus(OrderSyncStatusEnum.remove_success.getStatus());
//                } else {
//                    LOGGER.error("== 开始同步有更新的数据到催收系统 推送还款失败==,orderNo:{}", order.getOrderNo());
//                    order.setSyncStatus(OrderSyncStatusEnum.remove_failed.getStatus());
//                }
//            } catch (Exception e) {
//                LOGGER.error("=======  推送collection请求结果 error  ======", e);
//                order.setSyncStatus(OrderSyncStatusEnum.remove_failed.getStatus());
//            }
//            ordersDao.updateByPrimaryKey(order);
//        });

    }

    @Override
    public void composeNote(CeCommentPushLogEntity ceCommentPushLogEntity) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("called_person_type", "0");
        jsonObject.put("operate_type", "1");
        jsonObject.put("result_type", "91");
        jsonObject.put("result_reason", "61");
        ceCommentPushLogEntity.setPushDetail(jsonObject.toString());

        ceCommentPushLogEntity.setStatus(1);
        commentPushLogDao.updateByPrimaryKey(ceCommentPushLogEntity);
    }


    /**
     * @param ceCommentPushLogEntity
     * @return 1 connected   1-7 willingness-to-repay
     * 1-11 willing to repay
     * 1-5 虚假个人信息
     * 2  no-answer
     * 3  empty-number / halt / shutdown
     * 4  reject / hang-up / pull-black
     */
    @Override
    public boolean sendNote(CeCommentPushLogEntity ceCommentPushLogEntity) {
        LOGGER.info("== 开始同步催记到甲方 ==");
        GreatRoyalCollectionTagEnum currentTag = GreatRoyalCollectionTagEnum.RNR_V2;

        for (GreatRoyalCollectionTagEnum e : GreatRoyalCollectionTagEnum.values()) {
            if (e.getType().equals(ceCommentPushLogEntity.getTargetType())) {
                currentTag = e;
            }
        }

        try {
            CeMerchantEntity ceMerchantEntity = merchantDao.queryMerchantByCode(ceCommentPushLogEntity.getMerchantCode());
            CeAgentAccountEntity account = agentAccountDao.getByAgentCode(ceCommentPushLogEntity.getAgentCode());
            CeOrdersEntity ceOrdersEntity = ordersDao.getOneByOrderNo(ceCommentPushLogEntity.getOriginNo());
            Any orderInfo = JsonIterator.deserialize(ceOrdersEntity.getOrderInfo());
            String time = "";
            if (currentTag.getCpType() == 10) {
                time = DateUtil.getDate("yyyy-MM-dd hh:mm:ss");
            }
            String url = ceMerchantEntity.getApiDomain() + "/collection/order/add-collection-log?id=" + orderInfo.get("id").toString();
            String params = "collection_target=10&collection_result=" + currentTag.getCpType() + "&promised_repayment_time=" + time + "&collection_remark=" + currentTag.getShortDesc();
            Map<String, String> headers = getHeaders(account);
            headers.put("X-Requested-With", "XMLHttpRequest");
            String result = HttpUtil.postFrom(url, headers, params);
            if (!result.contains("Welcome to SCP")) {
                LOGGER.info("== GreatRoyal开始同步催记到甲方 success==");
                return true;
            } else {
                LOGGER.error("== GreatRoyal开始同步催记到甲方 error==");
            }

        } catch (Exception e) {
            LOGGER.info("== GreatRoyal 开始同步催记到甲方 异常==", e);
        }
        return false;
    }

    @Override
    public String updateRepaymentLink(String collectionNo, boolean isReduce) {
        CeOrdersEntity ceOrdersEntity = ordersDao.getOneByCollectionNo(collectionNo);
        CeAgentAccountEntity accountEntity = agentAccountDao.getByAgentCode(ceOrdersEntity.getAgentCode());
        CeMerchantEntity ceMerchantEntity = merchantDao.queryMerchantByCode(ceOrdersEntity.getMerchantCode());

        Any orderInfoJson = JsonIterator.deserialize(ceOrdersEntity.getOrderInfo());
        String link = "";
        Map<String, String> headers = getHeaders(accountEntity);
        headers.put("X-Requested-With", "XMLHttpRequest");
        HashMap<String, String> params = Maps.newHashMap();
        String url = ceMerchantEntity.getApiDomain() + "/collection/order/get-order-links?id=" + orderInfoJson.get("id").toString();
        LOGGER.info("== 获取还款链接请求  GreatRoyal== url:{},params:{}", url, JsonStream.serialize(params));

        String result = HttpUtil.getPage(url, params, headers);
        Any resultJson = JsonIterator.deserialize(result);
        if (resultJson.get("code").toInt() == 0) {
            link = resultJson.get("data").get("repayment_link").toString();
            String appLink = resultJson.get("data").get("app_link").toString();
            updateAppLink(ceOrdersEntity.getOrderNo(), appLink, ceOrdersEntity.getMerchantCode());
            LOGGER.info("== 获取还款链接 ==,link:{}", link);
        } else {
            LOGGER.error("== 获取还款链接失败 ==,account:{},loanId:{}", ceOrdersEntity.getAgentCode(), ceOrdersEntity.getOrderNo());
        }

        return link;
    }

    @Override
    public String updateExtensionRepaymentLink(String collectionNo,boolean isOpen) {
        CeOrdersEntity ceOrdersEntity = ordersDao.getOneByCollectionNo(collectionNo);
        CeAgentAccountEntity accountEntity = agentAccountDao.getByAgentCode(ceOrdersEntity.getAgentCode());
        CeMerchantEntity ceMerchantEntity = merchantDao.queryMerchantByCode(ceOrdersEntity.getMerchantCode());

        Any orderInfoJson = JsonIterator.deserialize(ceOrdersEntity.getOrderInfo());
        String renewLink = "";
        Map<String, String> headers = getHeaders(accountEntity);
        headers.put("X-Requested-With", "XMLHttpRequest");
        HashMap<String, String> params = Maps.newHashMap();
        String url = ceMerchantEntity.getApiDomain() + "/collection/order/get-order-links?id=" + orderInfoJson.get("id").toString();
        LOGGER.info("== 获取还款链接请求  GreatRoyal== url:{},params:{}", url, JsonStream.serialize(params));

        String result = HttpUtil.getPage(url, params, headers);
        Any resultJson = JsonIterator.deserialize(result);
        if (resultJson.get("code").toInt() == 0) {
            renewLink = resultJson.get("data").get("extension_link").toString();
            String appLink = resultJson.get("data").get("app_link").toString();
            updateAppLink(ceOrdersEntity.getOrderNo(), appLink, ceOrdersEntity.getMerchantCode());
            LOGGER.info("== 获取展期还款链接 ==,renewLink:{}", renewLink);
        } else {
            LOGGER.error("== 获取展期还款链接失败 ==,account:{},loanId:{}", ceOrdersEntity.getAgentCode(), ceOrdersEntity.getOrderNo());
        }
        return renewLink;
    }

    @Override
    public String addPaymentOrder(String orderNo, String fileName, String fileUrl, String utr, String remark, String amount) {
        return "";
    }

    public static String getLastDayDate(String date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtil.getDate(date, "yyyy-MM-dd"));
        c.add(Calendar.DATE, -1);
        Date start = c.getTime();
        return format.format(start);
    }

    @Override
    public String queryPaymentOrderResult(String orderNo, String utr) {
        return "";
    }

    @Override
    public String checkOrdersPaid(String orderNo) {
        CeOrdersEntity ordersEntity = ordersDao.getTodayOneByOrderNo(orderNo);
        CeAgentAccountEntity agentAccount = agentAccountDao.getByAgentCode(ordersEntity.getAgentCode());
        CeMerchantEntity merchant = merchantDao.queryMerchantByCode(ordersEntity.getMerchantCode());
        Map<String, String> headers = getHeaders(agentAccount);
        Map<String, String> params = Maps.newHashMap();


        return "no paid";
    }

    public static void main(String[] args) {
        try {

            String url = "http://home.tocollect7.com/site/login";
            AsyncHttpClient c = new DefaultAsyncHttpClient();
            Future<Response> f = c.prepareGet(url)
                    .addFormParam("LoginForm[username]", "biggS-1")
                    .addFormParam("LoginForm[password]", "mss_1199")
                    .addFormParam("LoginForm[verifyCode]", "pufu")
                    .addFormParam("LoginForm[rememberMe]", "0")
                    .addFormParam("login-button", "")
                    .addFormParam("_csrf-backend", "35094a27c01f0eb371a2ccf809277a2248f5cbc4ed297b6675444b69fb8c14dda:2:{i:0;s:13:\"_csrf-backend\";i:1;s:32:\"5XzgDcPwiHfXKhUJRvzMu_PnZNwVbm2N\";}")
                    .addHeader("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE)
                    .execute(new AsyncCompletionHandler<Response>() {
                        @Override
                        public void onThrowable(Throwable t) {
                            throw new RuntimeException("exception");
                        }

                        @Override
                        public Response onCompleted(Response response) {
                            return response;
                        }
                    });
            long startTime = System.currentTimeMillis();
            Response response;
            while (true) {
                response = f.get();
                if (response != null) {
                    break;
                } else {
                    long endTime = System.currentTimeMillis();
                    // 大于8秒认为查询数据失败
                    if ((endTime - startTime) / 1000 > 8) {
                        throw new RuntimeException("exception");
                    }
                }
            }
            String responseBody = response.getResponseBody();
            LOGGER.info(responseBody);
        }catch (Exception e){

        }
    }

    private static String getBirthDayByAge(Integer age) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();

        c.setTime(new Date());
        c.add(Calendar.YEAR, -age);
        Date y = c.getTime();
        return format.format(y);
    }
}
